// ValidationAspects
// Written by Mike Saunders
// Released under Microsoft Public License (Ms-PL)
using System.Text.RegularExpressions;
using NUnit.Framework;
using ValidationAspects.Exceptions;
using ValidationAspects.Factories;

namespace TestValidationAspects.Factories
{
	[TestFixture]
	public class TestIsEmail
	{
		private static readonly IsEmail _isEmail = new IsEmail();

		private static void Fail(string value)
		{
			Test.Throws<ValidateIsEmailException>(() => _isEmail.Create<string>().Invoke(value, new MockValidationContext()), new ValidateIsEmailException(value).Message);
		}

		private static void Pass(string value)
		{
			_isEmail.Create<string>().Invoke(value, new MockValidationContext());
		}

		[SetUp]
		public void SetUp()
		{
			IsEmail.ResetRegex();
		}

		[Test]
		public void Test_default_get_IsStrict()
		{
			Assert.IsFalse(new IsEmail().IsStrict);
		}

		[Test]
		public void Test_IsEmail_Strict()
		{
			_isEmail.IsStrict = true;

			Fail(string.Empty);

			Pass("JOE@home.com");
			Pass("joe.bob@home.com");
			Pass("joe@his.home.com");
			Pass("joe@his.home.place");
			Pass("joe@joebob.name");
			Pass("joe@home.org");
			Pass("joe&bob@bob.com");
			Pass("~joe@bob.com");
			Pass("joe$@bob.com");
			Pass("joe+bob@bob.com");
			Pass("o'reilly@there.com");

			Fail("joe");
			Fail("joe@home");
			Fail("a@b.c");
			Fail("joe-bob[at]home.com");
			Fail("joe.@bob.com");
			Fail(".joe@bob.com");
			Fail("joe<>bob@bob.come");
		}

		[Test]
		public void Test_IsEmail_Lenient()
		{
			_isEmail.IsStrict = false;

			Fail(string.Empty);

			Pass("JOE@home.com");
			Pass("joe.bob@home.com");
			Pass("joe@his.home.com");
			Pass("joe@his.home.place");
			Pass("joe@joebob.name");
			Pass("joe@home.org");
			Pass("joe&bob@bob.com");
			Pass("~joe@bob.com");
			Pass("joe+bob@bob.com");
			Pass("o'reilly@there.com");
			Pass("a@b.c");
			Pass(".joe@bob.com");
			Pass("joe<>bob@bob.come");

			Fail("joe");
			Fail("joe@home");
			Fail("joe-bob[at]home.com");
			Fail("joe.@bob.com");
			Fail("joe$@bob.com");
		}

		[Test]
		public void Test_validation_skips_null_value()
		{
			_isEmail.IsStrict = true;
			Pass(null);

			_isEmail.IsStrict = false;
			Pass(null);
		}

		[Test]
		public void Test_set_and_use_different_StrictRegex()
		{
			IsEmail.StrictRegex = new Regex("test");
			_isEmail.IsStrict = true;

			Pass("test");
		}

		[Test]
		public void Test_set_and_use_different_LenientRegex()
		{
			IsEmail.LenientRegex = new Regex("test");
			_isEmail.IsStrict = false;

			Pass("test");
		}
	}
}